package com.example.understandvideo.tool;

import com.example.understandvideo.pojo.TargetParagraphInfo;
import com.fasterxml.jackson.databind.exc.InvalidFormatException;
import com.volcengine.StringUtil;
import org.apache.commons.lang.StringUtils;
import org.apache.poi.xwpf.usermodel.*;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTBody;
import org.openxmlformats.schemas.wordprocessingml.x2006.main.CTP;
import org.springframework.util.CollectionUtils;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.*;
import java.util.function.Predicate;
import java.util.stream.Collectors;

import static com.example.understandvideo.tool.ExcelTool.readAndCleanJson;

public class WordTool {

    public static void main(String[] args) {
        String inputFilePath = "D:\\home\\V4校验.docx";

        try (FileInputStream fis = new FileInputStream(inputFilePath);
             XWPFDocument document = new XWPFDocument(fis)) {
            List<String> targetList = new ArrayList<>();
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                if (paragraph.getStyle()!=null) {
                    targetList.add(paragraph.getText());
                }
            }
            List<String> duplicates = findDuplicates(targetList);
            System.out.println("重复项: " + duplicates); // 输出: [苹果, 香蕉]
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    public static List<String> findDuplicates(List<String> targetList) {
        Set<String> seen = new HashSet<>();
        return targetList.stream()
                .filter(n -> !seen.add(n))
                .distinct()
                .collect(Collectors.toList());
    }
    /**
     * 依据excel提取的json文件，将json文件中的title对应的word内容，改成对应格式
     *
     */

    static void dealWordFromJsonV2() throws IOException {
        String titleFlag = "title.json";
        List<String> flagList = new ArrayList<>();
        try {
            flagList = Files.readAllLines(Paths.get(titleFlag));
        }catch (Exception e){
            e.printStackTrace();
        }
        if(CollectionUtils.isEmpty(flagList)){
            return;
        }
        for(String flag : flagList){
            System.out.println(flag);
        }
        String inputFilePath = "D:\\home\\新增-未处理格式-生成数据-v2.docx";
        String outputFilePath = "D:\\home\\新增-处理格式-生成数据-v1.docx";
        String sytle6String = "6级标题格式模板#flag";

        try (FileInputStream fis = new FileInputStream(inputFilePath);
             XWPFDocument document = new XWPFDocument(fis)) {
            String style6 = null;
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                if (paragraph.getText().contains(sytle6String)) {
                    style6 = paragraph.getStyle();
                    System.out.println(style6);
                    System.out.println(paragraph.getText());
                }
            }
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                String targetText = paragraph.getText();
                Boolean flag = false;
                for (String flagText : flagList) {
                    if (targetText.contains(flagText)) {
                        flag = true;
                    }
                }
                if (flag) {
                    paragraph.setStyle(style6);
                    // 调试信息：打印段落的样式名称
                    System.out.println("Paragraph style: " + paragraph.getStyle());
                }
            }

            try (FileOutputStream fos = new FileOutputStream(outputFilePath)) {
                document.write(fos);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
    /**
     * 切割word文档
     */
    static void splitWord(String inputFilePath) {
        File file = new File(inputFilePath);
        try (FileInputStream fis = new FileInputStream(inputFilePath);
             XWPFDocument doc = new XWPFDocument(fis)) {
            for (XWPFParagraph paragraph : doc.getParagraphs()) {

            }
            // 保存文档
            try (FileOutputStream fos = new FileOutputStream("D:\\home\\test3-4-1-output-1.docx")) {
                doc.write(fos);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    static void dealWordFromJson() throws IOException {
        String jsonFilePath = "data-back.json";
        // 读取 JSON 文件
        List<String> cleanedLines = readAndCleanJson(jsonFilePath);

        String inputFilePath = "D:\\home\\测试.docx";
        String outputFilePath = "D:\\home\\output.docx";
        try (FileInputStream fis = new FileInputStream(inputFilePath);
             XWPFDocument doc = new XWPFDocument(fis)) {
            for (String line : cleanedLines) {
                if (StringUtils.isNotBlank(line)) {
                    String data = line.replaceAll("### ", "").replaceAll("##", "").replaceAll("- ", "").split("（")[0];
                    XWPFParagraph paragraph = doc.createParagraph();
                    if (line.contains("###")) {
                        paragraph.setStyle("3");
                    }
                    XWPFRun run = paragraph.createRun();
                    run.setText(data);
                }
            }
            // 保存文档
            try (FileOutputStream fos = new FileOutputStream(outputFilePath)) {
                doc.write(fos);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    static void dealWord() {
        String inputFilePath = "D:\\home\\测试.docx";
        String outputFilePath = "D:\\home\\前评估附件1：咪咕公司VR能力平台六期XR沉浸观赛平台单项工程需求规格说明书--0426.docx";
        try (FileInputStream fis = new FileInputStream(inputFilePath);
             XWPFDocument doc = new XWPFDocument(fis)) {
            String searchString = "##test##";
            for (XWPFParagraph paragraph : doc.getParagraphs()) {
//                if (paragraph.getText().contains(searchString)) {
                if (paragraph.getStyle() != null && paragraph.getStyle().equals("6")) {
                    System.out.println("Paragraph origin text: " + paragraph.getText());
                    // 获取原始文本并替换指定字符串
                    String originalText = paragraph.getText();
                    String target1 = originalText.replaceAll(searchString, "");
                    String target2 = target1.replaceAll("功能点：", "");
                    String target3 = target2.replaceAll("- \\*\\*", "");
                    String target5 = target3.replaceAll("[0-9.,]", "");
                    String target4 = target5.replaceAll("D", "3D");
                    String target6 = target4.replaceAll("I3D", "ID");
                    String modifiedText = target6.replaceAll("\\*\\*", "");
                    System.out.println("Paragraph origin text: " + modifiedText);
                    // 手动清空段落中的所有 XWPFRun
                    List<XWPFRun> runs = new ArrayList<>(paragraph.getRuns());
                    for (XWPFRun run : runs) {
                        paragraph.removeRun(paragraph.getRuns().indexOf(run));
                    }

                    // 创建新的 XWPFRun 并设置修改后的文本
                    XWPFRun newRun = paragraph.createRun();
                    newRun.setText(modifiedText);
                    // 调试信息：打印段落的样式名称
                    System.out.println("Paragraph style: " + paragraph.getStyle());
                }
            }
            // 保存文档
            try (FileOutputStream fos = new FileOutputStream(outputFilePath)) {
                doc.write(fos);
            }

        } catch (IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    /**
     * 批量在多个目标段落后插入内容（安全版本）
     *
     * @param document 目标文档对象
     * @throws Exception 异常
     */
    public static void batchInsertAfterParagraphs(XWPFDocument document,
                                                  List<TargetParagraphInfo> targets) throws Exception {
        // 2. 从后往前安全插入
        Collections.sort(targets, Comparator.comparingInt(a -> -a.index));
        for (TargetParagraphInfo target : targets) {
            // 准备插入内容
            List<XWPFParagraph> newParas = prepareContentParagraphs(document, target.content);

            // 执行插入操作
            insertParagraphsAt(document, target.index, newParas);
        }
    }

    /**
     * 将原始文本数据转换为格式化的段落列表
     *
     * @param doc     目标文档对象（用于创建段落）
     * @param rawData 原始文本数据（支持\n\n分块和\n换行）
     * @return 格式化后的段落列表（已清除默认样式）
     * @throws IllegalArgumentException 当输入数据为空时抛出
     */
    public static List<XWPFParagraph> prepareContentParagraphs(XWPFDocument doc, String rawData) {
        // 1. 参数验证
        if (doc == null) throw new IllegalArgumentException("文档对象不能为空");
        if (rawData == null || rawData.trim().isEmpty())
            throw new IllegalArgumentException("输入数据不能为空");

        // 2. 初始化结果容器
        List<XWPFParagraph> paragraphs = new ArrayList<>();

        // 3. 按双换行符分割内容块
        String[] contentBlocks = rawData.split("\n");

        // 4. 遍历处理每个内容块
        for (String block : contentBlocks) {
            // 4.1 创建新段落
            XWPFParagraph para = doc.createParagraph();

            // 4.2 清除默认样式（关键步骤）
            para.setStyle(null);

            // 4.3 处理段落文本
            processParagraphText(para, block);

            paragraphs.add(para);
        }

        return paragraphs;
    }

    /**
     * 段落文本处理核心逻辑
     *
     * @param para    目标段落
     * @param rawText 原始文本内容
     */
    private static void processParagraphText(XWPFParagraph para, String rawText) {
        // 1. 按单换行符分割文本行
        String[] lines = rawText.split("\n");

        // 2. 创建文本运行对象
        XWPFRun firstRun = para.createRun();
        firstRun.setText(lines[0]); // 首行文本

        // 3. 处理后续换行内容
        for (int i = 1; i < lines.length; i++) {
            // 3.1 创建新文本运行
            XWPFRun run = para.createRun();

            // 3.2 添加文本内容
            run.setText(lines[i]);

            // 3.3 插入换行符（保持段落连续性）
            run.addBreak(BreakType.TEXT_WRAPPING);
        }
    }

    /**
     * 获取段落在文档段落列表中的索引位置
     *
     * @param document   目标文档对象
     * @param targetPara 需要查找的段落对象
     * @return 段落索引（从0开始），未找到返回-1
     */
    public static int getParagraphIndex(XWPFDocument document, XWPFParagraph targetPara) {
        List<XWPFParagraph> paragraphs = document.getParagraphs();
        for (int i = 0; i < paragraphs.size(); i++) {
            // 使用对象引用比较确保准确性
            if (paragraphs.get(i) == targetPara) {
                return i;
            }
        }
        return -1; // 未找到匹配段落
    }

    /**
     * 在指定位置插入多个段落（底层XML操作）
     */
    public static void insertParagraphsAt(XWPFDocument doc, int insertIndex,
                                          List<XWPFParagraph> newParas) {
        // 新增：插入位置合法性检查
        int maxValidIndex = doc.getParagraphs().size();
        insertIndex = Math.min(Math.max(insertIndex, 0), maxValidIndex);

        CTBody body = doc.getDocument().getBody();
        CTP[] pArray = body.getPArray();
        List<CTP> newPList = new ArrayList<>(Arrays.asList(pArray));

        // 反向插入逻辑（保持原有）
        for (int i = newParas.size() - 1; i >= 0; i--) {
            int actualIndex = insertIndex + i; // 关键修正：考虑多段落插入偏移
            if (actualIndex > newPList.size()) {
                actualIndex = newPList.size();
            }
            newPList.add(actualIndex, newParas.get(i).getCTP());
        }

        body.setPArray(newPList.toArray(new CTP[0]));
    }

    //    static void test2(){
//        String inputFilePath = "C:\Users\xjc.ARCVIDEO\Downloads\inputs.docx";
//        String outputFilePath = "C:\Users\xjc.ARCVIDEO\Downloads\output.docx";
//        String searchString = "##test##";
//
//        try (FileInputStream fis = new FileInputStream(inputFilePath);
//             XWPFDocument document = new XWPFDocument(fis)) {
//            for (XWPFParagraph paragraph : document.getParagraphs()) {
//                if (paragraph.getStyle() != null && paragraph.getStyle().equals("6")) {
//
//
//                    // 获取原始文本并替换指定字符串
//                    String originalText = paragraph.getText();
//                    String modifiedText = originalText.replace(searchString, "");
//
//                    // 手动清空段落中的所有 XWPFRun
//                    List<XWPFRun> runs = new ArrayList<>(paragraph.getRuns());
//                    for (XWPFRun run : runs) {
//                        paragraph.removeRun(paragraph.getRuns().indexOf(run));
//                    }
//
//                    // 创建新的 XWPFRun 并设置修改后的文本
//                    XWPFRun newRun = paragraph.createRun();
//                    newRun.setText(modifiedText);
//
//                    // 调试信息：打印段落的样式名称
//                    System.out.println("Paragraph style: " + paragraph.getStyle());
//                }
//            }
//
//            try (FileOutputStream fos = new FileOutputStream(outputFilePath)) {
//                document.write(fos);
//            }
//
//        } catch (IOException e) {
//            e.printStackTrace();
//        }
//    }
    public static void test1(String inputFilePath) {
        String inputFilePathV2 = "D:\\home\\补充脚本.docx";
        String outputFilePath = "D:\\home\\测试V6.docx";
        String searchString = "##test##";
        String sytle6String = "直播任务任务名称模糊查询flag";

        try (FileInputStream fis = new FileInputStream(inputFilePathV2);
             XWPFDocument document = new XWPFDocument(fis)) {
            String style6 = null;
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                if (paragraph.getText().contains(sytle6String)) {
                    style6 = paragraph.getStyle();
                    System.out.println(style6);
                    System.out.println(paragraph.getText());
                }
            }
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                if (paragraph.getText().contains(searchString)) {
                    paragraph.setStyle(style6);
                    // 获取原始文本并替换指定字符串
                    String originalText = paragraph.getText();
                    String modifiedText = originalText.replaceAll(searchString, "");

                    // 手动清空段落中的所有 XWPFRun
                    List<XWPFRun> runs = new ArrayList<>(paragraph.getRuns());
                    for (XWPFRun run : runs) {
                        paragraph.removeRun(paragraph.getRuns().indexOf(run));
                    }

                    // 创建新的 XWPFRun 并设置修改后的文本
                    XWPFRun newRun = paragraph.createRun();
                    newRun.setText(modifiedText);

                    // 调试信息：打印段落的样式名称
                    System.out.println("Paragraph style: " + paragraph.getStyle());
                }
            }

            try (FileOutputStream fos = new FileOutputStream(outputFilePath)) {
                document.write(fos);
            }

        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    public static void test2(String inputFilePath) {
        String sytleString = "数据名称模糊查询Flag";

        try (FileInputStream fis = new FileInputStream(inputFilePath);
             XWPFDocument document = new XWPFDocument(fis)) {
            String style = null;
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                if (paragraph.getText().contains(sytleString)) {
                    style = paragraph.getStyle();
                    break;
                }
            }
            List<String> content = new ArrayList<>();
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                if (paragraph.getStyle() != null && paragraph.getStyle().equals(style)) {
                    content.add(paragraph.getText());
                }
            }
            System.out.println(content);
            System.out.println(content.size());
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    public static void test3(String inputFilePath) {
        List<String> titleList = new ArrayList<>();
        List<String> reptitleList = new ArrayList<>();
        try (FileInputStream fis = new FileInputStream(inputFilePath);
             XWPFDocument document = new XWPFDocument(fis)) {
            for (XWPFParagraph paragraph : document.getParagraphs()) {
                if (paragraph.getStyle() != null) {
                    if(CollectionUtils.isEmpty(titleList)){
                        titleList.add(paragraph.getText());
                    }else {
                        Boolean flag = true;
                        for(String title : titleList){
                            if(paragraph.getText().equals(title)){
                                reptitleList.add(paragraph.getText());
                                flag = false;
                            }
                        }
                        if(flag){
                            titleList.add(paragraph.getText());
                        }
                    }

                }
            }
            System.out.println("==========所有标题begin===========");
            System.out.println(String.join("\n",titleList));
            System.out.println("==========所有标题end===========");
            System.out.println("==========重复标题begin===========");
            System.out.println(String.join("\n", reptitleList));
            System.out.println("==========重复标题end===========");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
